package com.jtcoding.chat.handler;

import com.jtcoding.chat.common.JacksonSerializer;
import com.jtcoding.chat.model.ChatRecord;
import com.jtcoding.chat.model.MessageDetail;
import com.jtcoding.chat.model.Result;
import com.jtcoding.chat.service.ChatService;
import com.jtcoding.chat.service.NettyService;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.charset.Charset;
import java.util.Objects;


/**
 * @Author jason.tang
 * @Date 2019/02/6 14:21
 * @Desc 聊天服务回调
 */
@Component
public class ChatServerHandler extends ChannelInboundHandlerAdapter {

    @Autowired
    private ChatService chatService;

    @Autowired
    private NettyService nettyService;

    /**
     * channelRead方法再接收到客户端发来的数据之后被回调
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf) msg;
        String str = byteBuf.toString(Charset.forName("utf-8"));
        if (str == null) {
            return;
        }
        MessageDetail messageDetail = JacksonSerializer.parseObject(str, MessageDetail.class);
        if (messageDetail == null) {
            return;
        }
        Channel channel = ctx.channel();
        switch (messageDetail.getMsgType()) {
            case 0:
                // 处理连接事件
                nettyService.putUserChannel(messageDetail.getChatRecord().getUserNum(), channel);
                channel.writeAndFlush(JacksonSerializer.toJSONString(Result.success("连接成功")));
                break;
            case 1:
                // 处理消息事件
                ChatRecord chatRecord = messageDetail.getChatRecord();
                // 判断接收消息的好友是否在线
                Channel friendChannel = nettyService.getChannelByNum(chatRecord.getFriendNum());
                if (friendChannel != null) {
                    String result = Objects.requireNonNull(JacksonSerializer.toJSONString(messageDetail));
                    friendChannel.writeAndFlush(getByteBuf(ctx, result));
                }
                chatService.addChatRecord(chatRecord);
                break;
            case 2:
                // 处理断开连接事件
                nettyService.removeUserChannelByNum(messageDetail.getChatRecord().getUserNum());
                channel.writeAndFlush(JacksonSerializer.toJSONString(Result.success("已断开连接")));
                break;
                default:
                    break;
        }
    }

    private ByteBuf getByteBuf(ChannelHandlerContext ctx, String string) {
        // 1. 获取二进制抽象ByteBuf（先获得内存管理器）
        ByteBuf buffer = ctx.alloc().buffer();

        // 2. 准备数据，指定字符串的字符集为utf-8
        byte[] bytes = string.getBytes(Charset.forName("utf-8"));

        // 3. 将二进制数据填充到ByteBuf
        buffer.writeBytes(bytes);

        return buffer;
    }
}
